<?php

class CustomMember extends DataExtension {
    private static $migrate_legacy_hashes = array(
        'blowfish' => 'base64',
    );
	
    private static $db = array(
        'Username' => 'Varchar',
        'Status' => "Dropdown('StatusList')"
    );
	
	private static $searchable_fields = array(
        'Username',
        'FirstName',
        'Surname',
        'Email',
        'Status'
    );
	
	private static $summary_fields = array(
        'Username',
        'FirstName',
        'Surname',
		'Email',
		'Status.Title'
    );

    private static $indexes = array(
        'Username' => true,
        'FirstName' => true,
        'Surname' => true,
        'Email' => true
    );
	
	private static $casting = array('LastLogin' => 'Datetime');
	
	function updateFieldLabels(&$labels) {
		$labels['FailedLoginCount'] = _t('CustomMember.FAILED_LOGIN', 'Failed Login');
		$labels['Name'] = _t('CustomMember.NAME', 'Full Name');
		$labels['Username'] = _t('CustomMember.USERNAME', 'Username');
		$labels['LastLogin'] = _t('CustomMember.LAST_LOGIN', 'Last Login');
		$labels['LastLoginIP'] = _t('CustomMember.LAST_LOGIN_IP', 'Last Login IP');
		$labels['Status'] = _t('CustomMember.STATUS', 'Status');
		$labels['Status.Title'] = _t('CustomMember.STATUS', 'Status');
		$labels['DecryptPassword'] = _t('Member.db_Password');
    }
	
	function populateDefaults() {
		$this->owner->SetStatusCode = StatusList::get_default_status_code();
        $this->owner->DateFormat = 'dd/MM/yyyy';
        $this->owner->TimeFormat = 'h:mm a';
    }
	
	function validate(ValidationResult $validationResult) {
		if($this->owner->Email == Security::default_admin_username()){
			$this->owner->Username = $this->owner->Email;
			$this->owner->IsAdmin = 1;
		}
		
        if(!$this->owner->Username) {
            $subvalid = new ValidationResult();
            $subvalid->error(_t('CustomMember.EMPTY_USERNAME', 'Empty member username'), "EMPTY_MEMBER_USERNAME");
            $validationResult->combineAnd($subvalid);
        }
        
        return $validationResult;
    }
	
	function updateValidator($validator){
		$validator = Injector::inst()->create('CustomMember_Validator');
	}

    function updateCMSFields(FieldList $fields) {
		$fields->insertBefore(TextField::create('Username', $this->owner->fieldLabel('Username')), 'Password');
		$fields->replaceField('Email', EmailField::create('Email', $this->owner->fieldLabel('Email')));
		$fields->dataFieldByName('Password')->showOnClick = false;
		
        if($this->owner->exists()) {
            $fields->makeFieldReadonly('Username');
			$fields->dataFieldByName('Username')->setIncludeHiddenField(true);
			$fields->makeFieldReadonly('FailedLoginCount');
        } else {
        	$fields->removeByName('Status');
        	$fields->removeByName('LastVisited');
            $fields->removeByName('FailedLoginCount');
			$fields->removeByName('HasConfiguredDashboard');
        }
    }

	function updateFrontendFields(FieldList $fields) {
		$fields->replaceField('Username', TextField::create('Username', $this->owner->fieldLabel('Username')));
		$fields->replaceField('Email', EmailField::create('Email', $this->owner->fieldLabel('Email')));
    }

	function updateMemberFormFields(FieldList $fields) {
        $fields->insertBefore(TextField::create('Name', $this->owner->fieldLabel('Name')), 'FirstName');
        $fields->replaceField('FirstName', HiddenField::create('FirstName', 'FirstName'));
        $fields->replaceField('Surname', HiddenField::create('Surname', 'Surname'));
		$fields->replaceField('Email', EmailField::create('Email', $this->owner->fieldLabel('Email')));

        $fields->removeByName('Password');
        $fields->removeByName('Locale');
        $fields->removeByName('Username');
		$fields->removeByName('Status');
        $fields->removeByName('DateFormat');
        $fields->removeByName('TimeFormat');
		$fields->removeByName('HasConfiguredDashboard');
    }

	function onBeforeWrite() {
        if($this->owner->Email == Security::default_admin_username()) {
            $this->owner->Username = $this->owner->Email;
			$this->owner->IsAdmin = 1;
        }
		
		if($this->owner->SetStatusCode != '') {
            $this->owner->Status = $this->owner->SetStatusCode;
        }
    }
	
	function getDecryptPassword(){
		if($this->owner->Password){
			$algorithm = $this->owner->PasswordEncryption ? $this->owner->PasswordEncryption : Config::inst()->get('Security', 'password_encryption_algorithm');
			$e = PasswordEncryptor::create_for_algorithm($algorithm);
			return ($e && method_exists($e, 'decrypt')) ? $e->decrypt($this->owner->Password, $this->owner->Salt, $this->owner) : '';
		}
	}
	
	function getLastLoginIP() {
        $login_attempt = DataObject::get_one('LoginAttempt', "MemberID = '" . $this->owner->ID . "' AND Status = 'Success'", false, 'Created DESC');
        if($login_attempt){
            return $login_attempt->IP;
        }
    }

    function getLastLogin() {
        $login_attempt = DataObject::get_one('LoginAttempt', "MemberID = '" . $this->owner->ID . "' AND Status = 'Success'", false, 'Created DESC');
        if($login_attempt){
            return $login_attempt->Created;
        }
    }
	
	function beforeMemberLoggedIn() {
    	$lang = Session::get('lang');
        Session::clear_all();
		Session::set('lang', $lang);
    }
	
	function canEdit($member) {
		return true;
    }

    function canView($member) {
        return true;
    }

    function canDelete($member) {
        return false;
    }

    function canCreate($member) {
        return true;
    }
}

class CustomMember_Validator extends RequiredFields {
	protected $customRequired = array(
		'FirstName',
		'Email',
		'Username'
	);


	/**
	 * Constructor
	 */
	public function __construct() {
		$required = func_get_args();

		if(isset($required[0]) && is_array($required[0])) {
			$required = $required[0];
		}

		$required = array_merge($required, $this->customRequired);

		parent::__construct($required);
	}

	/**
	 * Check if the submitted member data is valid (server-side)
	 *
	 * Check if a member with that email doesn't already exist, or if it does
	 * that it is this member.
	 *
	 * @param array $data Submitted data
	 * @return bool Returns TRUE if the submitted data is valid, otherwise
	 *              FALSE.
	 */
	public function php($data) {
		$valid = parent::php($data);
		
		$identifierField = Member::config()->unique_identifier_field;
		$SQL_identifierField = Convert::raw2sql($data[$identifierField]);
		$member = DataObject::get_one('Member', "\"$identifierField\" = '{$SQL_identifierField}'");

		// if we are in a complex table field popup, use ctf[childID], else use ID
		if(isset($_REQUEST['ctf']['childID'])) {
			$id = $_REQUEST['ctf']['childID'];
		} elseif(isset($_REQUEST['ID'])) {
			$id = $_REQUEST['ID'];
		} else {
			$id = null;
		}

		if($id && is_object($member) && $member->ID != $id) {
			$uniqueField = $this->form->Fields()->dataFieldByName($identifierField);
			$this->validationError(
				$uniqueField->id(),
				_t(
					'CustomMember.VALIDATIONMEMBEREXISTS',
					'A member already exists with the same %s',
					array('identifier' => strtolower($identifierField))
				),
				'required'
			);
			$valid = false;
		}

		// Execute the validators on the extensions
		if($this->extension_instances) {
			foreach($this->extension_instances as $extension) {
				if(method_exists($extension, 'hasMethod') && $extension->hasMethod('updatePHP')) {
					$valid &= $extension->updatePHP($data, $this->form);
				}
			}
		}

		return $valid;
	}

}